package openglhandmaid
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.geom.Vector3D;
	import flash.utils.ByteArray;
	
	public class Model
	{
		[Embed(source="african_head.obj",mimeType="application/octet-stream")]
    	private var africanHeadObj:Class;
    	[Embed(source="african_head_diffuse.png")]
    	private var african_head_diffuse:Class;
		
		private var vertices:Vector.<Vector3D>;
		private var uv:Vector.<Array>;
		private var faces:Vector.<Array>;
		
		public var diffusemap:BitmapData;
		
		public function Model()
		{
			var bytes:ByteArray = new africanHeadObj();
			readBytes(bytes);
			
			diffusemap = Bitmap(new african_head_diffuse()).bitmapData;
		}
		
		// https://github.com/noonat/models-molehill/blob/master/src/com/phuce/obj/OBJ.as
		private function readBytes(bytes:ByteArray):void 
		{
			vertices = new Vector.<Vector3D>();
			uv = new Vector.<Array>();
			faces = new Vector.<Array>();
			
			bytes.position = 0;
			
		  	var text:String = bytes.readUTFBytes(bytes.bytesAvailable);
		  	var lines:Array = text.split(/[\r\n]+/);
		  	for each (var line:String in lines)
		  	{
		    	// Trim whitespace from the line
				line = line.replace(/^\s*|\s*$/g, '');
				if (line == '' || line.charAt(0) === '#') 
				{
		  			// Blank line or comment, ignore it
		  			continue;
				}
				// Split line into fields on whitespace
				var fields:Array = line.split(/\s+/);
				switch (fields[0].toLowerCase()) 
				{
					// Vertex position
		  			case 'v':
		    			vertices.push(
		      				new Vector3D(parseFloat(fields[1]), parseFloat(fields[2]), parseFloat(fields[3]))
		      			);
		    		break;
					case 'vt':
		            	uv.push( [parseFloat(fields[1]), 1.0 - parseFloat(fields[2])] );
						//trace(uv[uv.length-1]) // Vector3D(0.185, 0.831, 0)
		            break;
		    		// Face indices, specified in sets of "position/uv/normal"
					case 'f':// f 205/185/205 207/187/207 204/188/204
		            	var face:Array = new Array();
		            	
			            for each (var tuple:String in fields.slice(1))
			            {
			            	var aTuple:Array = tuple.split("/");
			              	face.push(parseFloat(aTuple[0]));
			              	face.push(parseFloat(aTuple[1]));
			              	face.push(parseFloat(aTuple[2]));			              
			            }
			            faces.push(face);
						//trace(face) // 1208,1256,1208,1088,1276,1088,1086,1257,1086
		            break;
				}
		  	}
		}
		public function getVertices():Vector.<Vector3D>
		{
			return vertices;
		}
		public function getFaces():Vector.<Array>
		{
			return faces;
		}
		public function getUV(iface:int, nvert:int):Vector3D
		{
			var idx:int = faces[iface][nvert]-1;
			var vector:Vector3D = new Vector3D(uv[idx][0]*diffusemap.width, uv[idx][1]*diffusemap.height);
			return vector;
		}
	}
}
